package code.c03_stackQueue.cSqQueue;

import org.omg.CORBA.PUBLIC_MEMBER;

/**
 * @author thinkpad - 83start
 * @version v1.0
 * @create 2022/10/8 19:10
 * @package code.c03_stackQueue.cSqQueue
 * @description 在循环队列CSqQueueClass <E> 中添加一个求元素个数的方法 size();
 * 对于一个整数循环队列 qu ,利用队列基本运算 和 size() 算法设计一个进队和出队第 K 个元素的算法。
 */

public class Exam_3_11 {

}

class CSqQueueClassK<E> {
    final int MAX_SIZE = 10;
    private E[] data;
    private int front, rear;

    public CSqQueueClassK() {
        data = (E[]) new Object[MAX_SIZE];
        front = 0;
        rear = 0;
    }
    // ================================ 基本运算 ================================

    /**
     * 判断是否队空
     *
     * @return
     */
    public boolean empty() {
        return front == rear;
    }

    /**
     * 入队操作
     *
     * @param e
     */
    public void push(E e) {
        if ((rear + 1) % MAX_SIZE == front) {
            throw new IllegalArgumentException("队满");
        }
        rear = (rear + 1) % MAX_SIZE;
        data[rear] = e;
    }

    /**
     * 出队操作
     *
     * @return
     */
    public E pop() {
        if (empty()) {
            throw new IllegalArgumentException("队空");
        }
        front = (front + 1) % MAX_SIZE;
        return (E) data[front];
    }

    /**
     * 获取队中第一个元素
     *
     * @return
     */
    public E peek() {
        if (empty()) {
            throw new IllegalArgumentException("队空");
        }
        return data[(front + 1) % MAX_SIZE];
    }

    /**
     * 返回队中元素个数
     *
     * @return
     */
    public int size() {
        return (rear - front - MAX_SIZE) % MAX_SIZE;
    }

    /**
     * 插入第 k 个 元素 e
     * @param qu
     * @param k
     * @param e
     * @return
     */
    public boolean pushk(CSqQueueClassK<E>qu,int k,E e){
        E x;
        int n = qu.size();
        // 当参数 k 错误，返回 false
        if (k<1 || k > n+1){
            return false;
        }
        // 当 k 在 元素队列中间时
        if (k<=n){
            // 循环处理所有的元素
            for (int i = 1; i <= n; i++) {
                if (i == k){ // 元素入队
                    qu.push(e);
                }
                x = qu.pop();// 出队
                qu.push(x);// 进队
            }
        }else { // k  = n + 1 时直接进队
            qu.push(e);
        }
        return true;
    }

    /**
     * 将第k 个元素出队
     * @param qu
     * @param k
     * @return
     */
    public E popk(CSqQueueClassK<E> qu,int k){
        E x,e = null;
        int n = qu.size();

        if (k<1 || k>n){
            throw new IllegalArgumentException("参数错误");
        }

        for (int i = 1; i <= n; i++) {
            x = qu.pop();
            if (i!= k){
               qu.push(x);
            }
            else {
                e= x;
            }

        }
        return e;
    }
}
